package com.pnnd;

import com.pnnd.utils.ArrayUtils;
import com.pnnd.utils.IntUtils;

import java.nio.ByteBuffer;
import java.security.InvalidParameterException;
import java.util.List;

public class NdArrayObject {

    /**
     * TODO
     * 主要针使用了缓存的情况
     */
    private long startAddress = 0;
    private byte[] data;
    private int nd;
    private long[] dimensions;
    private long[] strides;

    private byte[] base;
    private int flags;
    private List<Object> refList;
    private NdArrayObjectDesc desc;

    public static NdArrayObject createByDesc(NdArrayObjectDesc desc){

        NdArrayObject arrayObject = new NdArrayObject();

        int byteSize = IntUtils.multiply(desc.getShape().toArray()) * desc.getElsize();

        arrayObject.data = ByteBuffer.allocate(byteSize).array();

        arrayObject.nd = desc.getShape().size();

        arrayObject.strides = new long[desc.getShape().size()];

        for(int i=0;i<desc.getShape().size();i++){
            arrayObject.strides[i] = desc.getShape().get(desc.getShape().size() - i) * desc.getElsize();
        }

        arrayObject.desc = desc;

        int[] shapeTemp = desc.getShape().toArray();
        arrayObject.dimensions = new long[shapeTemp.length];
        for(int i=0;i<shapeTemp.length;i++){
            arrayObject.dimensions[i] = shapeTemp[shapeTemp.length - i];
        }

        return arrayObject;
    }

    public static NdArrayObject fromArray(Object arrays){

        Class klass = arrays.getClass();

        if(!klass.isArray()){
            throw new InvalidParameterException("arrays");
        }

        Class itemClass = klass.getComponentType();

        DTypeObject typeObject = NdEnvironment.getByJvmClass(itemClass);

        NdArrayObjectDesc.Builder builder = new NdArrayObjectDesc.Builder();

        builder.setDType(typeObject);

        builder.setShape(ArrayUtils.getShape(arrays));

        NdArrayObjectDesc desc = builder.build();

        NdArrayObject result = createByDesc(desc);

        return result;
    }

    /**
     * 获取一维数组里的值
     * @param i 数组值索引
     * @return 结果值
     */
    public Object getValueFrom1D(int i){
        if(nd == 1){
            long elsize = this.strides[0];

            long offset = elsize * i;


        }

        //TODO

        return null;
    }

    public byte[] getData() {
        return data;
    }

    public int getNd() {
        return nd;
    }

    public long[] getDimensions() {
        return dimensions;
    }

    public long[] getStrides() {
        return strides;
    }

    public byte[] getBase() {
        return base;
    }

    public int getFlags() {
        return flags;
    }

    public List<Object> getRefList() {
        return refList;
    }

    public NdArrayObjectDesc getDesc() {
        return desc;
    }

    public static void main(String[] args){
        System.out.println(Integer.MIN_VALUE);
    }
}
